const request = require("request"); // 用于下载文件
const fs = require("fs");
const path = require("path");
const ffmpeg = require("fluent-ffmpeg"); // 用于转码
const tmp = require("tmp");

const uuid = (len = 8) => {
  const characters =
    "0123456789ABCDEFGHIJK12134567895LMNOPQRSTUVWXYZ123456789abcdefghijklmnopqrstuvwxyz0123456789";
  let result = "";
  for (let i = 0; i < len; i++) {
    result += characters.charAt(Math.floor(Math.random() * characters.length));
  }
  return result;
};

const createTempDir = () => {
  return new Promise((resolve, reject) => {
    tmp.dir({ unsafeCleanup: true }, (err, dir, cleanupHandle) => {
      if (err) {
        reject(err);
      } else {
        resolve({ dir, cleanupHandle });
      }
    });
  });
};

const downloadFile = (url, destDir) => {
  return new Promise((resolve, reject) => {
    const parsedUrl = new URL(url);
    const fileName = parsedUrl.pathname.split("/").pop();
    const dest = path.join(destDir, fileName);
    request(url)
      .pipe(fs.createWriteStream(dest))
      .on("finish", () => {
        resolve(dest); // 返回文件的完整路径
      })
      .on("error", (error) => {
        reject(error);
      });
  });
};

const transformVideo = async (inputFilePath, outputbaseFolder) => {
  const outputDir = path.join(outputbaseFolder, "test");
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }
  const metadata = await new Promise((resolve, reject) => {
    ffmpeg.ffprobe(inputFilePath, (err, metadata) => {
      if (err) {
        reject(err);
      } else {
        resolve(metadata);
      }
    });
  });

  // 获取视频流信息
  const videoStream = metadata.streams.find(stream => stream.codec_type === 'video');
  const infos = {
    width: videoStream.width,
    height: videoStream.height,
    duration: videoStream.duration,
  };
  const poster = path.join(outputDir, 'poster.jpg');

  // 获取文件大小
  const stats = await fs.promises.stat(inputFilePath);
  infos.size = stats.size;

  console.log(inputFilePath, "inputFilePath", outputDir);
  const outputM3u8 = path.join(outputDir, "output.m3u8");

  return new Promise((resolve, reject) => {
    ffmpeg(inputFilePath)
      .videoCodec("libx264")
      .outputOptions("-hls_time 10") // 设置每个HLS分段的时间长度为10秒
      .outputOptions("-hls_list_size 0") // 设置HLS播放列表中包含所有分段
      .outputOptions("-preset veryfast") // 使用较快的编码预设
      .outputOptions("-crf 18") // 设置CRF值以保持高画质
      .format("hls")
      .output(outputM3u8)
      .on("start", function (commandLine) {
        console.log("Spawned FFmpeg with command: " + commandLine);
      })
      .on("error", function (err) {
        console.log("An error occurred: " + err.message);
        reject(err);
      })
      .on("end", async function () {
        console.log("Finished HLS conversion");

        // 生成截图
        try {
          await new Promise((resolve, reject) => {
            ffmpeg(inputFilePath)
              .outputOptions('-vframes 1')
              .output(poster)
              .on("start", function (commandLine) {
                console.log("Spawned FFmpeg for screenshot with command: " + commandLine);
              })
              .on("error", function (err) {
                console.log("An error occurred during screenshot generation: " + err.message);
                reject(err);
              })
              .on("end", function () {
                console.log("Finished screenshot generation");
                infos.poster = poster;
                resolve();
              })
              .run();
          });

          console.log("Finished processing");
          resolve({ outputDir, infos });
        } catch (screenshotErr) {
          reject(screenshotErr);
        }
      })
      .run();
  });
};


module.exports = {
  createTempDir,
  downloadFile,
  transformVideo,
};
